﻿using System.Collections;
using System.Linq.Expressions;
using System.Reflection.Metadata;
using Microsoft.EntityFrameworkCore;
using static System.Linq.Expressions.Expression;

namespace EFCore一对多关系配置
{
  internal class Program
  {
    /// <summary>
    /// 查找指定列的数据   动态表达式树
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="propertyNames"></param>
    /// <returns></returns>
    static IEnumerable<Object[]> Query<T>(params string[] propertyNames) where T : class
    {
      var p = Expression.Parameter(typeof(T));
      List<Expression> propExprList = new List<Expression>();
      foreach (var property in propertyNames)
      {
        Expression propExpr = Convert(MakeMemberAccess(p, typeof(T).GetProperty(property)), typeof(object));
        propExprList.Add(propExpr);
      }
      var newArrayExpr = NewArrayInit(typeof(object), propExprList);
      var selectExpr = Lambda<Func<T, object[]>>(newArrayExpr, p);

      using MyDBContext db = new();
      return db.Set<T>().Select(selectExpr).ToArray();
    }

    static async Task Main(string[] args)
    {

      Dog dog = new Dog(19, "1");
      
      Dog dog2 = new Dog(19, "1");
      Dog dog1 = dog with { Name = "kk" }; //创建副本

      Article article=new Article();
    

      Console.WriteLine(dog2==dog);

      using MyDBContext db = new();

      var select = db.Articles.Select(a => new { a.Title, a.Message });
      var list = Query<Article>("Id","Message");

      //Article article = new Article { Title = "微信朋友圈可以发实况图了", Message = "据媒体19日消息，微信朋友圈可以发实况图了，照片包含动态画面和声音。你尝试了吗？" };
      //article.Comments.Add(new Comment {Message= "抱歉 本人非苹果用户不享受此权益" });
      //article.Comments.Add(new Comment {Message= "终于能发了 " });
      //article.Comments.Add(new Comment {Message= "你要能把视频和照片放一起发而不是合并，因为即便是这样也没能拯救你的视频号，何必呢" });
      //article.Comments.Add(new Comment {Message= "现在不喜欢发朋友圈了，发好的，别人会妒忌陷害你，发不好的，别人又在笑话你。还是保持神秘感比较好!" });
      //db.Articles.Add(article);
      ////不需要在单独插入Comment 和 指定Comment的Article EFCore自动完成
      //db.SaveChanges();

      //  var a=db.Articles.Single(x => x.Id == 1);

      //var a=db.Articles.Include(a=>a.Comments).Single(x => x.Id == 1);
      //Console.WriteLine(  $"{a.Title}\r\n{a.Message}");
      //foreach (var item in a.Comments)
      //{
      //  Console.WriteLine($"{item.Message}");
      //}
      #region 在EFCore中通过 SQL语句查询
      //string name = "据媒体19日消息，微信朋友圈可以发实况图了，照片包含动态画面和声音。你尝试了吗？";
      //int age = 10;
      //// ExecuteSqlInterpolatedAsync直接执行非查询 SQL语句  @表示多行
      //await db.Database.ExecuteSqlInterpolatedAsync(@$"insert into T_Acticle(Title,Message) 
      //  select Title,{name}
      //  from T_Acticle");
      // string title = "微信朋友圈可以发实况图了";
      //实体 sql语句查询
      //var order = db.Articles.FromSqlInterpolated($@"select * from T_Acticle where Title like {title}");
      //foreach (var item in order.Include(a => a.Comments).OrderBy(a => Guid.NewGuid()))
      //{
      //  Console.WriteLine(item.Id);
      //}
      //db.Articles.RemoveRange()


      #endregion
      #region EFCore通过Ado.Net 执行任意SQL语句
      //var conn = db.Database.GetDbConnection();
      //if (conn.State != System.Data.ConnectionState.Open)
      //{
      //  await conn.OpenAsync();
      //}
      //using (var cmd = conn.CreateCommand())
      //{
      //  cmd.CommandText = "select Price,Count(*) from T_Acticle groupby Price";
      //  using var reader = await cmd.ExecuteReaderAsync();
      //  while (await reader.ReadAsync())
      //  {
      //    double price = reader.GetDouble(0);
      //    int count = reader.GetInt32(1);
      //    Console.WriteLine($"{price}:{count}");
      //  }
      //} 

      //通过Depper执行原生SQL语句
      //var items = db.Database.GetDbConnection().Query<T>($"");
      #endregion

      //  var a= db.Comments.Include(:“An expression of non-boolean a=>a.TheArticle).Single(a=>a.Id==3);
      //Console.WriteLine($"{a.Id},{a.Message},---{a.TheArticle.Title}");

      //var a = db.Comments.Select(c => new { Id = c.Id, AId = c.TheArticle.Id }).Single(a => a.Id == 2);
      //var q1 = db.Comments.Skip(10 * 3).Take(10);
      ////Console.WriteLine($"{a.Id},{a.AId}");
      //double a1 = Math.Ceiling(1.2);
      //Console.WriteLine(double.MaxValue);
      //Console.WriteLine(long.MaxValue);
      //Console.WriteLine(double.MaxValue / long.MaxValue);
      //如果遇到 Include 性能问题，可以设置外键属性 TheArticleId与生成的数据库对应，并在Configure里 .HasForeignKey(a=>a.TheArticleId)显示申明 。除非必要无需这个操作

      var a = db.Articles.IgnoreQueryFilters().Where(a => a.Id > 5);//忽略全局筛选器


    }
  }
}
